home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 1 Issue 2 / PDCD-1 - Issue 02.iso / _utilities / utilities / 003 / motorola / Sources / c / util < prev   
Text File  |  1993-07-18  |  14KB  |  551 lines

  1. #include <setjmp.h>
  2. #include <stdarg.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <ctype.h>
  7.  
  8. #include "mselect.h"    /*external selection of microprocessor symbol table*/
  9. #include "proto.h"
  10. #include "as.h"
  11. #include "structs.h"
  12. #include "riscos.h"
  13. #include "extvars.h"
  14.  
  15. #define FATAL 2
  16. #define SERIOUS 1
  17. #define WARNING 0
  18. #define MAXERR 100
  19.  
  20. /* Throwback routines Copyright ⌐ 1992 Niklas R÷jemo */
  21.  
  22. extern struct oper table[];
  23.  
  24. int             pedantic = 1;
  25.  
  26. static int      ThrowbackStarted;
  27. static char    *Filename;
  28.  
  29. static char     errbuf[1024];
  30.  
  31.  
  32.  
  33. /*
  34.  * void errorInit(int throwback,char *np) { if(throwback) Filename =
  35.  * CanonicalisePath(np); else Filename = 0; }
  36.  */
  37.  
  38. void 
  39. errorInit(int throwback, char *np)
  40. {
  41.         if (throwback)
  42.                 Filename = np;
  43.         else
  44.                 Filename = 0;
  45. #ifdef DEBUG
  46.         printf("filename = %s\n", np);
  47. #endif
  48. }
  49.  
  50. void 
  51. errorFinish(void)
  52. {
  53.         if (ThrowbackStarted > 0) {
  54.                 ThrowbackStarted = 0;
  55.                 ThrowbackEnd();
  56.         }
  57. }
  58.  
  59. static void 
  60. TB(int level, int lineno, char *error)
  61. {
  62.         os_error       *err;
  63.         if (!Filename)
  64.                 return;
  65.         if (!ThrowbackStarted) {
  66.                 err = ThrowbackStart();
  67.                 if (err) {
  68.                         fprintf(stderr, "ThrowbackStart %s\n", err->errmess);
  69.                         exit(-1);
  70.                 }
  71.                 err = ThrowbackSendStart(Filename);
  72.                 if (err) {
  73.                         if (pedantic)
  74.                                 fprintf(stderr, "ThrowbackSendStart %s", err->errmess);
  75.                         ThrowbackStarted = -1;
  76.                 } else
  77.                         ThrowbackStarted = 1;
  78.         }
  79.         if (ThrowbackStarted > 0)
  80.                 ThrowbackSendError(level, lineno, error);
  81. }
  82.  
  83. /*
  84.  * fatal --- fatal error handler
  85.  */
  86. void
  87. fatal(char *str)
  88. {
  89.         pouterror(FATAL, str);  /* added ver TER_2.0 4 Jul 89 */
  90.         TB(FATAL, Local_Line_num, str);
  91.  
  92. #ifdef IBM                      /* changed ver TER_2.0 */
  93.         exit(-1);
  94. #else
  95.         exit(10);               /* Amiga & UNIX prefer positive numbers for
  96.                                  * error minimal error is 10 (no system prob) */
  97. #endif
  98.         return;                 /* never executed */
  99. }
  100.  
  101. /*
  102.  * error --- error in a line print line number and error
  103.  */
  104. void
  105. error(char *str)
  106. {
  107.  
  108.         /*
  109.          * if(N_files > 1)      commented out test for N_files in rel TER_2.0
  110.          * because a single command line source file (which is what N_file
  111.          * counts) can have multiple include source files.
  112.          */
  113.  
  114.         pouterror(SERIOUS, str);
  115.         TB(SERIOUS, Local_Line_num, str);
  116. }
  117.  
  118. /*
  119.  * warn --- trivial error in a line print line number and error
  120.  */
  121. void
  122. warn(char *str)
  123. {
  124.         /*
  125.          * if(N_files > 1)      commented out in rel TER_2.0 same reason as
  126.          * above
  127.          */
  128.         pouterror(WARNING, str);
  129.         TB(WARNING, Local_Line_num, str);
  130. }
  131.  
  132.  
  133. /*
  134.  * delim --- check if character is a delimiter
  135.  */
  136. int
  137. delim(char c)
  138. {
  139.         if (any(c, " \t\n"))
  140.                 return (YES);
  141.         return (NO);
  142. }
  143.  
  144. /*
  145.  * skip_white --- move pointer to next non-whitespace char
  146.  */
  147. char           *
  148. skip_white(char *ptr)
  149. {
  150.         while (*ptr == BLANK || *ptr == TAB)
  151.                 ptr++;
  152.         return (ptr);
  153. }
  154.  
  155. /*
  156.  * eword --- emit a word to code file
  157.  */
  158. void
  159. eword(int wd)
  160. {
  161.         emit(hibyte(wd));
  162.         emit(lobyte(wd));
  163. }
  164.  
  165. /*
  166.  * emit --- emit a byte to code file
  167.  */
  168. int
  169. emit(unsigned char byte)
  170. {
  171. #ifdef DEBUG
  172.         printf("%2x @ %4x\n", byte, Pc);
  173. #endif
  174.         if (Pass == 1) {
  175.                 Pc++;
  176.                 return (YES);
  177.         }
  178.         if (P_total < P_LIMIT)
  179.                 P_bytes[P_total++] = byte;
  180.         E_bytes[E_total++] = byte;
  181.         Pc++;
  182.         if (E_total == E_LIMIT)
  183.                 f_record();
  184.         return;
  185. }
  186.  
  187. /*
  188.  * f_record --- flush record out in `S1' format
  189.  */
  190. void
  191. f_record(void)
  192. {                               /* made void for ANSI C compat ver TER_2.0
  193.                                  * 6/18/89 */
  194.         int             i;
  195.         int             chksum;
  196.  
  197.         if (Pass == 1)
  198.                 return;
  199.         if (E_total == 0) {
  200.                 E_pc = Pc;
  201.                 return;
  202.         }
  203.         F_total += E_total;     /* total bytes in file ver (TER)2.01 19 Jun
  204.                                  * 89 */
  205.         chksum = E_total + 3;   /* total bytes in this record */
  206.         chksum += lobyte(E_pc);
  207.         chksum += E_pc >> 8;
  208.         fprintf(Objfil, "S1");  /* record header preamble */
  209.         hexout(E_total + 3);    /* byte count +3 */
  210.         hexout(E_pc >> 8);      /* high byte of PC */
  211.         hexout(lobyte(E_pc));   /* low byte of PC */
  212.         for (i = 0; i < E_total; i++) {
  213.                 chksum += lobyte(E_bytes[i]);
  214.                 hexout(lobyte(E_bytes[i]));     /* data byte */
  215.         }
  216.         chksum = ~chksum;       /* one's complement */
  217.         hexout(lobyte(chksum)); /* checksum */
  218.         if (CRflag == 1)        /* test for CRflag added ver TER_1.1 */
  219.                 fprintf(Objfil, "%c\n", CR);    /* print in IBM format for
  220.                                                  * some PROM boxes */
  221.         else
  222.                 fprintf(Objfil, "\n");  /* this is original statement */
  223.         E_pc = Pc;
  224.         E_total = 0;
  225. }
  226.  
  227. char           *hexstr = "0123456789ABCDEF";
  228.  
  229. void
  230. hexout(int byte)
  231. {
  232.  
  233.         byte = lobyte(byte);
  234.         fprintf(Objfil, "%c%c", hexstr[byte >> 4], hexstr[byte & 017]);
  235.         return;
  236. }
  237.  
  238. /*
  239.  * print_line --- pretty print input line
  240.  */
  241. void
  242. print_line(void)
  243. {
  244.         int             i;
  245.         register char  *ptr;
  246.  
  247.         fprintf(Listfil, "%04d ", Line_num);
  248.         if (P_total || P_force)
  249.                 {fprintf(Listfil,"%04x", Old_pc);}
  250.         else
  251.                 {fprintf(Listfil,"    ");}
  252.  
  253.         for (i = 0; i < P_total && i < 6; i++)
  254.                 {fprintf(Listfil, " %02x", lobyte(P_bytes[i]));}
  255.         for (; i < 6; i++)
  256.                 {fprintf(Listfil,"   ");}
  257.         fprintf(Listfil,"  ");
  258.  
  259.         if (Cflag) {
  260.                 if (Cycles)
  261.                         {fprintf(Listfil, "[%2d ] ", Cycles);}
  262.                 else
  263.                         {fprintf(Listfil,"      ");}
  264.         }
  265.         ptr = Line;
  266.         while (*ptr != '\n')    /* just echo the line back out */
  267.                 {fputc(*ptr++,Listfil);}
  268.         for (; i < P_total; i++) {
  269.                 if (i % 6 == 0)
  270.                         {fprintf(Listfil,"\n    ");};
  271.                 fprintf(Listfil, " %02x", lobyte(P_bytes[i]));
  272.         }
  273.         if (Pflag50 && (++Page_lines >= PageLen))     /* form feed if flag set */
  274.                 NewPage();      /* ver (TER) 2.02 19 Jun 89 */
  275.         fprintf(Listfil,"\n");
  276. }
  277.  
  278. /*
  279.  * any --- does str contain c?
  280.  */
  281. int
  282. any(char c, char *str)
  283. {
  284.         while (*str != EOS)
  285.                 if (*str++ == c)
  286.                         return (YES);
  287.         return (NO);
  288. }
  289.  
  290. /*
  291.  * mapdn --- convert A-Z to a-z
  292.  */
  293. char
  294. mapdn(char c)
  295. {
  296.         if (c >= 'A' && c <= 'Z')
  297.                 return ((char) (c + 040));      /* cast value to char for
  298.                                                  * ANSI C, ver TER_2.0 */
  299.         return (c);
  300. }
  301.  
  302. /*
  303.  * lobyte --- return low byte of an int
  304.  */
  305. unsigned char
  306. lobyte(int i)
  307. {
  308.         return (i & 0xFF);
  309. }
  310.  
  311.  
  312. /*
  313.  * hibyte --- return high byte of an int
  314.  */
  315. unsigned char
  316. hibyte(int i)
  317. {
  318.         return ((i >> 8) & 0xFF);
  319. }
  320.  
  321. /*
  322.  * head --- is str2 the head of str1?
  323.  */
  324. int
  325. head(char *str1, char *str2)
  326. {
  327.         while (*str1 != EOS && *str2 != EOS) {
  328.                 if (*str1 != *str2)
  329.                         break;
  330.                 str1++;
  331.                 str2++;
  332.         }
  333.         if (*str1 == *str2)
  334.                 return (YES);
  335.         if (*str2 == EOS)
  336.                 if (any(*str1, " \t\n,+-];*"))
  337.                         return (YES);
  338.         return (NO);
  339. }
  340.  
  341. /*
  342.  * alpha --- is character a legal letter
  343.  */
  344. int
  345. alpha(char c)
  346. {
  347.         if (c <= 'z' && c >= 'a')
  348.                 return (YES);
  349.         if (c <= 'Z' && c >= 'A')
  350.                 return (YES);
  351.         if (c == '_')
  352.                 return (YES);
  353.         if (c == '.')
  354.                 return (YES);
  355.         return (NO);
  356. }
  357.  
  358.  
  359. /*
  360.  * alphan --- is character a legal letter or digit
  361.  */
  362. int
  363. alphan(char c)
  364. {
  365.         if (alpha(c))
  366.                 return (YES);
  367.         if (c <= '9' && c >= '0')
  368.                 return (YES);
  369.         if (c == '$')
  370.                 return (YES);   /* allow imbedded $ */
  371.         if (c == '@')
  372.                 return (YES);   /* allow imbedded @, added ver TER_2.0 added
  373.                                  * to permit redefinable variables */
  374.         return (NO);
  375. }
  376.  
  377. /*
  378.  * white --- is character whitespace?
  379.  */
  380. int
  381. white(char c)
  382. {
  383.         if (c == TAB || c == BLANK || c == '\n')
  384.                 return (YES);
  385.         return (NO);
  386. }
  387.  
  388. /*
  389.  * alloc --- allocate memory
  390.  */
  391. char           *
  392. alloc(int nbytes)
  393. {
  394.  
  395.         return (malloc(nbytes));
  396. }
  397.  
  398. /*
  399.  * FNameGet --- Find a file name <file> or "file" in the Operand string added
  400.  * ver TER_2.0 6/17/89 note: this routine will return a file name with white
  401.  * space if between delimeters.  This is permitted in AmigaDOS.  Other DOS
  402.  * may hiccup or just use name up to white space
  403.  */
  404.  
  405. int
  406. FNameGet(char *NameString)
  407. /* char *NameString;        pointer to output string */
  408. {
  409.         char           *frompoint;      /* pointers to input string, don't
  410.                                          * bash Operand */
  411.         char           *topoint;/* pointer to output string, don't bash
  412.                                  * NameString */
  413.  
  414.         frompoint = Operand;    /* include file name is in parsed string
  415.                                  * Operand */
  416.         topoint = NameString;   /* copy of pointer to increment in copying */
  417.         if (*frompoint != '<' && *frompoint != '"')
  418.                 return (0);     /* bad syntax */
  419.         frompoint++;            /* skip < or " */
  420.  
  421.         while (*frompoint != '>' && *frompoint != '"') {        /* look for delimeter */
  422.                 if (*frompoint == EOS)
  423.                         return (0);     /* missing delimeter */
  424.                 *topoint++ = *frompoint++;      /* copy path & file name for
  425.                                                  * DOS */
  426.         }
  427.  
  428.         *topoint = EOS;         /* terminate file name */
  429. #ifdef DEBUG2
  430.         printf("FNameGet: file name=%s\n", NameString);
  431. #endif
  432.         return (1);             /* proper syntax anyway */
  433. }
  434.  
  435. /*
  436.  * --- strsave()  find a place to save a string & return pointer to it added
  437.  * ver TER_2.0 6/18/89  function taken from Kernighan & Ritchie 78
  438.  */
  439. char           *
  440. strsave(char *s)
  441. {
  442.         char           *p;
  443.  
  444.         if ((p = alloc(strlen(s) + 1)) != NULL)
  445.                 strcpy(p, s);
  446.         return (p);
  447. }
  448.  
  449. /*
  450.  * pouterror() ---- print out standard error header added rel TER_2.0 6/18/89
  451.  */
  452.  
  453. void
  454. pouterror(int err_type, char *str)
  455. {
  456.         fprintf(stderr, "%s, line no. ", Argv[Cfn]);    /* current file name */
  457.         fprintf(stderr, "%d: ", Local_Line_num);        /* current line number */
  458.         fprintf(stderr, "%s\n", str);
  459.         /*
  460.          * NOTE: THERE IS NO \n ! Calling procedure supplies suffixing error
  461.          * message and \n. viz. file pseudo.c procedure do_pseudo in case
  462.          * INCLUDE. Note also that error count is incremented.
  463.          */
  464.         Page_lines++;           /* increment lines per page */
  465.         if (err_type != WARNING) {
  466.                 Err_count++;
  467.         }
  468. }
  469.  
  470. /*
  471.  * New Page() --- form feed a new page, print heading & inc page number Moved
  472.  * here from do_pseudo (pseudo.c) in ver (TER) 2.02 19 Jun 89 so that can
  473.  * call from print_line() as well for p50 option.
  474.  */
  475.  
  476. void
  477. NewPage(void)
  478. {
  479.         Page_lines = 0;         /* ver TER_2.08 so that OPT PAGE works */
  480.         fprintf(Listfil, "\n\f");
  481.         fprintf(Listfil, "%-10s", Argv[Cfn]);
  482.         fprintf(Listfil, "                                   ");
  483.         fprintf(Listfil, "page %3d\n", Page_num++);
  484. }
  485.  
  486.  
  487. /*
  488.  * LastChar() ----- return a pointer to the last character in a string
  489.  * Exception: will return garbage if NULL string
  490.  */
  491.  
  492. char           *
  493. LastChar(char *strpt)
  494. /* strpt;     pointer to string to be examined */
  495. {
  496.         char           *c;
  497.  
  498.         c = strpt;              /* don't zap original */
  499.         while (*c != EOS)       /* search for end */
  500.                 c++;
  501.         return (--c);           /* back up one to last character */
  502. }
  503.  
  504.  
  505. #define OS_FSControl                 0x29
  506. #define DDEUtils_ThrowbackRegister   0x42585
  507. #define DDEUtils_ThrowbackUnRegister 0x42586
  508. #define DDEUtils_ThrowbackStart      0x42587
  509. #define DDEUtils_ThrowbackSend       0x42588
  510. #define DDEUtils_ThrowbackEnd        0x42580
  511. #define Throwback_ReasonProcessing     0
  512. #define Throwback_ReasonErrorDetails   1
  513. #define Throwback_ReasonInfoDetails    2
  514.  
  515.  
  516.  
  517. os_error       *
  518. ThrowbackStart(void)
  519. {
  520.         return os_swi0(os_X | DDEUtils_ThrowbackStart);
  521. }
  522.  
  523. static char    *ErrorFile;
  524.  
  525. os_error       *
  526. ThrowbackSendStart(char *filename)
  527. {
  528.         ErrorFile = filename;
  529.         return os_swi3(os_X | DDEUtils_ThrowbackSend,
  530.                        Throwback_ReasonProcessing, 0, (int) filename);
  531. }
  532.  
  533. os_error       *
  534. ThrowbackSendError(int level, int lineno, char *error)
  535. {
  536.         if (level == ThrowbackInfo)
  537.                 return os_swi6(os_X | DDEUtils_ThrowbackSend,
  538.                             Throwback_ReasonInfoDetails, 0, (int) ErrorFile,
  539.                                lineno, 0, (int) error);
  540.         else
  541.                 return os_swi6(os_X | DDEUtils_ThrowbackSend,
  542.                            Throwback_ReasonErrorDetails, 0, (int) ErrorFile,
  543.                                lineno, level, (int) error);
  544. }
  545.  
  546. os_error       *
  547. ThrowbackEnd(void)
  548. {
  549.         return os_swi0(os_X | DDEUtils_ThrowbackEnd);
  550. }
  551.